package com.dongdong.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.dongdong.mapper.TbSeckillGoodsMapper;
import com.dongdong.mapper.TbSeckillOrderMapper;
import com.dongdong.pojo.TbSeckillGoods;
import com.dongdong.pojo.TbSeckillGoodsExample;
import com.dongdong.pojo.TbSeckillOrder;
import com.dongdong.util.IdWorker;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@org.springframework.stereotype.Service
public class SeckillServiceImpl implements SeckillService {
    @Resource
    private TbSeckillGoodsMapper seckillGoodsMapper;
    @Resource
    private TbSeckillOrderMapper seckillOrderMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Override
    public List<TbSeckillGoods> selectAll() {
        //将String类型的value值序列化
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        //先查缓存 缓存中没有则查询数据库，同时将查询的结果放入redis
        List<TbSeckillGoods> goodsList = (List<TbSeckillGoods>)redisTemplate.boundHashOps("goodsList").values();
        if (goodsList.isEmpty()){
            TbSeckillGoodsExample example = new TbSeckillGoodsExample();
            example.createCriteria().andStatusEqualTo("1");//审核状态
            Date now = new Date();
            example.createCriteria().andStartTimeLessThanOrEqualTo(now);//秒杀开始时间段
            example.createCriteria().andEndTimeGreaterThanOrEqualTo(now);//秒杀结束时间段
            example.createCriteria().andStockCountGreaterThan(0);//库存数量必须大于零
            goodsList = seckillGoodsMapper.selectByExample(example);
            //放入缓存(采用流的形式)
            //把库存抽取出来 放在预减库存里
            goodsList.stream().forEach(goods->
            {
                    redisTemplate.boundHashOps("goodsList").put(goods.getId(),goods);
                    redisTemplate.boundValueOps(goods.getId()).set(goods.getStockCount().toString());
            }
            );
        }
        return goodsList;
    }

    @Override
    public TbSeckillGoods findGoodsById(Long id) {
        return (TbSeckillGoods) redisTemplate.boundHashOps("goodsList").get(id);
    }

    @Override
    public void createOrder(Long id, String username) {
        //1,从redis中查询数据
        //2,判断商品库存是否为null，是否为0
        String stockCount = (String)redisTemplate.boundValueOps(id).get();
        if (stockCount == null || Integer.parseInt(stockCount) <= 0){
            throw new RuntimeException("商品已经售罄！");

        }
        //3,减库存
       // goods.setStockCount(goods.getStockCount() - 1);
        Long decrement = redisTemplate.boundValueOps(id).decrement();
        //减库的商品重新放入redis
        if (decrement <= 0){
            TbSeckillGoods goods =  (TbSeckillGoods)redisTemplate.boundHashOps("goodsList").get(id);
            //更新数据库
            seckillGoodsMapper.updateByPrimaryKeySelective(goods);
            //说明已经是最后一件
            //删除缓存
            redisTemplate.boundHashOps("goodsList").delete(id);
           //删除库存
            redisTemplate.delete(id);
        }
        //4,创建订单(使用mq异步创建订单 串行化)，也可以使用锁的机制（分布式锁）
        Map map = new HashMap<String,Object>();
        map.put("id",id);
        map.put("username",username);
        rocketMQTemplate.convertAndSend("seckill-topic",map);

    }
    @Override
    public Long getOrderId(String username) {
        return (Long)redisTemplate.boundHashOps("order").get(username);
    }
}
